package com.ly.ocw.service.weixin;

import java.io.IOException;
import java.util.Date;
import java.util.List;

import org.apache.http.client.ClientProtocolException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.ly.ocw.comm.DateUtil;
import com.ly.ocw.comm.RegisterFrom;
import com.ly.ocw.entity.MarketingAccount;
import com.ly.ocw.entity.weixin.WeixinEventPush;
import com.ly.ocw.entity.weixin.WeixinEventPushArticle;
import com.ly.ocw.entity.weixin.WeixinScanLog;
import com.ly.ocw.entity.weixin.WeixinSubscribeLog;
import com.ly.ocw.exception.ServerException;
import com.ly.ocw.repository.weixin.WeixinEventPushArticleDao;
import com.ly.ocw.repository.weixin.WeixinEventPushDao;
import com.ly.ocw.repository.weixin.WeixinScanLogDao;
import com.ly.ocw.repository.weixin.WeixinSubscribeLogDao;
import com.ly.ocw.repository.weixin.WeixinUserInfoDao;
import com.ly.ocw.service.CrmMemberService;
import com.ly.ocw.service.MarketingAccountService;
import com.ly.ocw.utils.XmlMapper;
import com.ly.ocw.vo.wx.Event;
import com.ly.ocw.vo.wx.MsgType;
import com.ly.ocw.vo.wx.WeixinMessage;
import com.ly.ocw.vo.wx.response.Article;
import com.ly.ocw.vo.wx.response.BaseMessage;
import com.ly.ocw.vo.wx.response.NewsMessage;

/**
 * 微信Message 处理service、 处理微信具体的消息
 * 
 * @author Peter
 *
 */
@Component
public class WeixinMessageProcessService {

	/**
	 * 10000+实景案例
	 */
	private static final String V1002_SJAL = "V1002_SJAL";

	/**
	 * 在线客服小好 eventkey
	 */
	private static final String V1001_KEFU = "V1001_KEFU";

	private static Logger logger = LoggerFactory.getLogger(WeixinMessageProcessService.class);

	@Autowired
	private WeixinEventPushDao weixinEventPushDao;

	@Autowired
	private WeixinEventPushArticleDao weixinEventPushArticleDao;

	@Autowired
	private WeixinSubscribeLogDao weixinSubscribeLogDao;

	@Autowired
	private WeixinScanLogDao weixinScanLogDao;

	@Autowired
	private MarketingAccountService marketingAccountService;

	@Autowired
	private WeixinUserInfoDao weixinUserInfoDao;

	@Autowired
	private WeixinCardService weixinCardService;

	@Autowired
	private CrmMemberService crmMemberService;

	// ========= 基本消息处理 ==============================
	/**
	 * 文本消息:消息转发到多客服
	 * 
	 * <pro>
	 * 
	 * <xml> <ToUserName><![CDATA[touser]]></ToUserName>
	 * <FromUserName><![CDATA[fromuser]]></FromUserName>
	 * <CreateTime>1399197672</CreateTime>
	 * <MsgType><![CDATA[transfer_customer_service]]></MsgType> </xml>
	 * 
	 * </pro>
	 * 
	 * @param msg
	 */
	public String processTextMsg(WeixinMessage msg) {
		String reponseXml = "";
		logger.info("文本消息:消息转发到客服");
		BaseMessage result = new BaseMessage();
		result.setCreateTime(msg.getCreateTime());
		result.setFromUserName(msg.getToUserName());
		result.setMsgType("transfer_customer_service");
		result.setToUserName(msg.getFromUserName());
		reponseXml = XmlMapper.toXml(result);
		return reponseXml;
	}

	// ========= 事件处理 ===================================

	private String createSubscribeMsg(WeixinMessage msg) {
		WeixinSubscribeLog log = new WeixinSubscribeLog();
		log.setCreateDate(new Date());
		log.setEvent(Event.subscribe.name());
		log.setOpenid(msg.getFromUserName());
		weixinSubscribeLogDao.save(log);

		String reponseXml = "";
		String eventType = WeixinEventPush.event_type_subscribe;
		String eventKey = "subscribe";

		NewsMessage news = createNews(msg, eventType, eventKey);
		reponseXml = XmlMapper.toXml(news);
		return reponseXml;
	}

	/**
	 * 普通订阅事件
	 * 
	 * @param msg
	 */
	public String processSubscribeMsg(WeixinMessage msg) {
		logger.info("普通订阅事件，注册账号");
		// 直接关注微信公众号（普通订阅） 注册账号
		marketingAccountService.register(msg.getFromUserName(), RegisterFrom.direct);

		// return createSubscribeMsg(msg);
		return createSubscribeMsg(msg);
	}

	/**
	 * 订阅事件:扫描带参数二维码事件，用户未关注时，进行关注后的事件推送
	 * 
	 * 提示：1.成功成为XX的下线； 2.已经是XXX的下线了。
	 * 
	 * @param msg
	 * @throws
	 */
	public String processScanForSubscribe(WeixinMessage msg) {
		logger.info("订阅事件:扫描带参数二维码事件，用户未关注时，进行关注后的事件推送");

		String openid = msg.getFromUserName();

		// 是否是老用户（已经有账号，取消关注后再次扫描经纪人的二维码）
		MarketingAccount marketingAccount = marketingAccountService.getByOpenid(openid);

		// 记录扫码日志
		// 分享微信公众号获取积分qrscene_
		String sceneStr = msg.getEventKey().replace("qrscene_", "");
		WeixinScanLog log = new WeixinScanLog();
		log.setCaseCode("subscribed");
		log.setCreateDate(new Date());
		log.setOpenid(openid);
		log.setParentSceneStr(sceneStr);
		// log.setSceneStr(sceneStr);
		log.setUpdateDate(new Date());

		if (marketingAccount != null) {
			logger.info("已关注过了,openid=" + openid);
			log.setCaseName("已关注 扫描二维码,关注时间[" + DateUtil.sdf_1.format(marketingAccount.getCreateDate()) + "]");
		} else {
			// 通过扫码关注 注册账号
			marketingAccountService.register(openid, sceneStr, RegisterFrom.scan);
		}

		weixinScanLogDao.save(log);
		return createSubscribeMsg(msg);
	}

	/**
	 * 扫描带参数二维码事件:用户已关注时的事件推送
	 * 
	 * @param msg
	 */
	public String processScan(WeixinMessage msg) {
		// ToUserName 开发者微信号
		// FromUserName 发送方帐号（一个OpenID）
		// CreateTime 消息创建时间 （整型）
		// MsgType 消息类型，event
		// Event 事件类型，SCAN
		// EventKey 事件KEY值，是一个32位无符号整数，即创建二维码时的二维码scene_id
		// Ticket 二维码的ticket，可用来换取二维码图片
		logger.info("扫描带参数二维码事件:用户已关注时的事件推送");

		// 分享微信公众号获取积分qrscene_
		String str = msg.getEventKey().replace("qrscene_", "");

		WeixinScanLog log = new WeixinScanLog();
		log.setCaseCode("subscribed");
		log.setCaseName("已关注 扫描二维码");
		log.setCreateDate(new Date());
		log.setOpenid(msg.getFromUserName());
		log.setParentSceneStr(str);
		// log.setSceneStr(sceneStr);
		log.setUpdateDate(new Date());

		weixinScanLogDao.save(log);

		return createSubscribeMsg(msg);
	}

	/**
	 * 点击菜单事件
	 * 
	 * @param msg
	 */
	public String processClick(WeixinMessage msg) {
		logger.info("点击菜单事件");
		String reponseXml = "";
		if (V1001_KEFU.equals(msg.getEventKey())) {

		} else if (V1002_SJAL.equals(msg.getEventKey())) {

		}
		return reponseXml;
	}

	/**
	 * 创建图文消息
	 * 
	 * @param msg
	 * @param eventType
	 *            事件类型
	 * @param eventKey
	 *            事件key
	 * @return
	 */
	private NewsMessage createNews(WeixinMessage msg, String eventType, String eventKey) {
		NewsMessage news = new NewsMessage();
		news.setCreateTime(msg.getCreateTime());
		news.setFromUserName(msg.getToUserName());
		news.setMsgType(MsgType.news.name());
		news.setToUserName(msg.getFromUserName());

		WeixinEventPush wixinEventPush = weixinEventPushDao.findEventCode(eventType, eventKey);
		if (wixinEventPush != null) {
			List<WeixinEventPushArticle> articleList = weixinEventPushArticleDao.findByEvnetCode(wixinEventPush.getEventCode());
			if (articleList != null) {
				news.setArticleCount(articleList.size());
				for (WeixinEventPushArticle arc : articleList) {
					Article a = new Article();
					a.setDescription(arc.getDescription());
					a.setTitle(arc.getTitle());
					a.setPicUrl(arc.getPicUrl());
					a.setUrl(arc.getUrl());
					news.getItem().getItems().add(a);
				}
			}
		}
		return news;
	}

	/**
	 * 取消订阅
	 * 
	 * @param msg
	 */
	public void processUnsubscribe(WeixinMessage msg) {
		WeixinSubscribeLog log = new WeixinSubscribeLog();
		log.setCreateDate(new Date());
		log.setEvent(Event.unsubscribe.name());
		log.setOpenid(msg.getFromUserName());
		weixinSubscribeLogDao.save(log);

	}

	/**
	 * 用户领取卡券事件
	 * 
	 * @param msg
	 * @return
	 */
	public String processUserGetCard(WeixinMessage msg) {
		logger.info("用户领取卡券事件");
		// 激活会员卡
		String cardId = msg.getCardId();
		String code = msg.getUserCardCode();

		try {
			weixinCardService.activateCard(cardId, code, msg.getFromUserName());
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ServerException e) {
			e.printStackTrace();
		}
		return "";
	}

	/**
	 * 用户查看卡券事件
	 * 
	 * @param msg
	 * @return
	 */
	public String processUserViewCard(WeixinMessage msg) {
		logger.info("用户查看卡券事件");
		String cardId = msg.getCardId();
		String code = msg.getUserCardCode();

		try {
			crmMemberService.updateDemoMemberInfo(cardId, code, msg.getFromUserName());
		} catch (Exception e) {
			logger.error("用户查看卡券事件 失败", e);
		}

		return "";
	}

	/**
	 * 用户删除卡券事件
	 * 
	 * @param msg
	 * @return
	 */
	public String processUserDelCard(WeixinMessage msg) {
		logger.info("用户删除卡券事件");
		return "";
	}

	/**
	 * <xml><ToUserName><![CDATA[gh_0c3c8b46d477]]></ToUserName>
	 * <FromUserName><![CDATA[oEnm8vuEicj9biDVF5KTe2xKGBeU]]></FromUserName>
	 * <CreateTime>1435825241</CreateTime> <MsgType><![CDATA[event]]></MsgType>
	 * <Event><![CDATA[card_pass_check]]></Event>
	 * <CardId><![CDATA[pEnm8vouydPgIZQjv0kfSjiVE3M0]]></CardId> </xml> 卡券审核通过事件
	 * 
	 * @param msg
	 * @return
	 */
	public String processCardPassCheck(WeixinMessage msg) {
		logger.info("卡券审核通过事件");
		weixinCardService.updateCardStatus(msg.getCardId(), "CARD_STATUS_VERIFY_OK");
		return "";
	}

	/**
	 * 卡券审核不通过事件
	 * 
	 * @param msg
	 * @return
	 */
	public String processCardNotPassCheck(WeixinMessage msg) {
		logger.info("卡券审核不通过事件");
		weixinCardService.updateCardStatus(msg.getCardId(), "CARD_STATUS_VERIFY_FAIL");
		return "";
	}

}
